﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Codemonk.Updater.Client.Common
{
    internal class SocketUpdateClient : IUpdateClient
    {
        private string requestAddress;
        public string RequestAddress
        {
            get { return requestAddress; }
            set
            {
                requestAddress = value;
                var array = requestAddress.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                if (array.Length != 3) throw new Exception("Invalid server");
                if (array[0].Trim().ToLower() != "tcp") throw new Exception("Only support tcp mode");
                IPAddress address = null;
                var ipstr = array[1].Substring("//".Length).Trim();
                if (ipstr == "localhost") address = IPAddress.Loopback;
                else IPAddress.TryParse(ipstr, out address);
                if (address == null) throw new Exception("Invalid server ");
                var portstr = array[2].Trim();
                int port = -1;
                int.TryParse(portstr, out port);
                if (port < 0) throw new Exception("Invalid server ");
                endPoint = new IPEndPoint(address, port);
            }
        }

        private IPEndPoint endPoint;

        public void SendUpdateInstruction(string file, string appid, Action<Exception> error, Action<System.IO.MemoryStream> back)
        {
            if (back == null || endPoint == null) return;

            System.Threading.ThreadPool.QueueUserWorkItem(state =>
            {
                try
                {
                    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    client.Connect(endPoint);
                    var data = Encoding.UTF8.GetBytes(string.Concat("file=", file, ";appid=", appid));
                    client.Send(BitConverter.GetBytes(data.Length), 0, 4, 0);
                    client.Send(data, 0, data.Length, 0);
                    MemoryStream stream = new MemoryStream();
                    data = new byte[4];
                    client.Receive(data, 0, 4, 0);
                    var length = BitConverter.ToInt32(data, 0);
                    int index = 0;
                    data = new byte[2048];
                    while (index < length)
                    {
                        int count = client.Receive(data, 0, 2048, 0);
                        if (count <= 0) break;
                        index += count;
                        stream.Write(data, 0, count);
                    }
                    stream.Seek(0, SeekOrigin.Begin);
                    back(stream);
                }
                catch (Exception ex)
                {
                    if (error != null) error(ex);
                }
            });
        }
    }
}
